<template>
  <div class="schema-editor">
    <div class="editor-tabs">
      <el-tabs v-model="activeTab" type="border-card">
        <!-- 可视化编辑器 -->
        <el-tab-pane label="可视化编辑" name="visual">
          <div class="visual-editor">
            <div class="schema-info">
              <el-form :model="schemaInfo" label-width="100px" size="small">
                <el-row :gutter="20">
                  <el-col :span="12">
                    <el-form-item label="Schema类型">
                      <el-select v-model="schemaInfo.type" style="width: 100%">
                        <el-option label="对象 (object)" value="object" />
                        <el-option label="数组 (array)" value="array" />
                        <el-option label="字符串 (string)" value="string" />
                        <el-option label="数字 (number)" value="number" />
                        <el-option label="整数 (integer)" value="integer" />
                        <el-option label="布尔值 (boolean)" value="boolean" />
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <el-col :span="12">
                    <el-form-item label="标题">
                      <el-input v-model="schemaInfo.title" placeholder="Schema标题" />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-form-item label="描述">
                  <el-input
                    v-model="schemaInfo.description"
                    type="textarea"
                    :rows="2"
                    placeholder="Schema描述"
                  />
                </el-form-item>
              </el-form>
            </div>

            <!-- 对象属性编辑 -->
            <div v-if="schemaInfo.type === 'object'" class="properties-editor">
              <div class="properties-header">
                <h4>属性定义</h4>
                <el-button type="primary" size="small" @click="addProperty">
                  添加属性
                </el-button>
              </div>
              
              <div class="properties-list">
                <div
                  v-for="(property, index) in properties"
                  :key="index"
                  class="property-item"
                >
                  <el-card shadow="never" class="property-card">
                    <el-form :model="property" label-width="80px" size="small">
                      <el-row :gutter="10">
                        <el-col :span="5">
                          <el-form-item label="属性名">
                            <el-input v-model="property.name" placeholder="属性名" />
                          </el-form-item>
                        </el-col>
                        <el-col :span="4">
                          <el-form-item label="类型">
                            <el-select v-model="property.type" style="width: 100%">
                              <el-option label="string" value="string" />
                              <el-option label="number" value="number" />
                              <el-option label="integer" value="integer" />
                              <el-option label="boolean" value="boolean" />
                              <el-option label="array" value="array" />
                              <el-option label="object" value="object" />
                            </el-select>
                          </el-form-item>
                        </el-col>
                        <el-col :span="5">
                          <el-form-item label="描述">
                            <el-input v-model="property.description" placeholder="属性描述" />
                          </el-form-item>
                        </el-col>
                        <el-col :span="4">
                          <el-form-item label="默认值">
                            <el-input v-model="property.default" placeholder="默认值" />
                          </el-form-item>
                        </el-col>
                        <el-col :span="3">
                          <el-form-item label="必填">
                            <el-checkbox v-model="property.required" />
                          </el-form-item>
                        </el-col>
                        <el-col :span="3">
                          <el-form-item label="操作">
                            <el-button
                              type="danger"
                              size="small"
                              @click="removeProperty(index)"
                              :icon="Delete"
                            />
                          </el-form-item>
                        </el-col>
                      </el-row>
                      
                      <!-- 字符串类型的额外配置 -->
                      <div v-if="property.type === 'string'" class="type-config">
                        <el-row :gutter="10">
                          <el-col :span="6">
                            <el-form-item label="最小长度">
                              <el-input-number
                                v-model="property.minLength"
                                :min="0"
                                size="small"
                                style="width: 100%"
                              />
                            </el-form-item>
                          </el-col>
                          <el-col :span="6">
                            <el-form-item label="最大长度">
                              <el-input-number
                                v-model="property.maxLength"
                                :min="0"
                                size="small"
                                style="width: 100%"
                              />
                            </el-form-item>
                          </el-col>
                          <el-col :span="12">
                            <el-form-item label="正则表达式">
                              <el-input v-model="property.pattern" placeholder="正则表达式" />
                            </el-form-item>
                          </el-col>
                        </el-row>
                      </div>
                      
                      <!-- 数字类型的额外配置 -->
                      <div v-if="['number', 'integer'].includes(property.type)" class="type-config">
                        <el-row :gutter="10">
                          <el-col :span="6">
                            <el-form-item label="最小值">
                              <el-input-number
                                v-model="property.minimum"
                                size="small"
                                style="width: 100%"
                              />
                            </el-form-item>
                          </el-col>
                          <el-col :span="6">
                            <el-form-item label="最大值">
                              <el-input-number
                                v-model="property.maximum"
                                size="small"
                                style="width: 100%"
                              />
                            </el-form-item>
                          </el-col>
                          <el-col :span="6">
                            <el-form-item label="倍数">
                              <el-input-number
                                v-model="property.multipleOf"
                                :min="0"
                                size="small"
                                style="width: 100%"
                              />
                            </el-form-item>
                          </el-col>
                        </el-row>
                      </div>
                      
                      <!-- 枚举值配置 -->
                      <div class="enum-config">
                        <el-form-item label="枚举值">
                          <el-select
                            v-model="property.enum"
                            multiple
                            filterable
                            allow-create
                            placeholder="输入枚举值"
                            style="width: 100%"
                          >
                          </el-select>
                        </el-form-item>
                      </div>
                    </el-form>
                  </el-card>
                </div>
              </div>
            </div>

            <!-- 数组类型编辑 -->
            <div v-if="schemaInfo.type === 'array'" class="array-editor">
              <h4>数组项配置</h4>
              <el-form :model="arrayItems" label-width="100px" size="small">
                <el-row :gutter="20">
                  <el-col :span="8">
                    <el-form-item label="项类型">
                      <el-select v-model="arrayItems.type" style="width: 100%">
                        <el-option label="string" value="string" />
                        <el-option label="number" value="number" />
                        <el-option label="integer" value="integer" />
                        <el-option label="boolean" value="boolean" />
                        <el-option label="object" value="object" />
                      </el-select>
                    </el-form-item>
                  </el-col>
                  <el-col :span="8">
                    <el-form-item label="最小项数">
                      <el-input-number
                        v-model="arrayItems.minItems"
                        :min="0"
                        style="width: 100%"
                      />
                    </el-form-item>
                  </el-col>
                  <el-col :span="8">
                    <el-form-item label="最大项数">
                      <el-input-number
                        v-model="arrayItems.maxItems"
                        :min="0"
                        style="width: 100%"
                      />
                    </el-form-item>
                  </el-col>
                </el-row>
                <el-form-item label="项描述">
                  <el-input
                    v-model="arrayItems.description"
                    placeholder="数组项描述"
                  />
                </el-form-item>
              </el-form>
            </div>
          </div>
        </el-tab-pane>

        <!-- JSON编辑器 -->
        <el-tab-pane label="JSON编辑" name="json">
          <div class="json-editor">
            <el-input
              v-model="jsonSchema"
              type="textarea"
              :rows="20"
              placeholder="请输入JSON Schema"
              class="json-textarea"
            />
            <div class="json-actions">
              <el-button @click="formatJson">格式化</el-button>
              <el-button @click="validateJson">验证</el-button>
              <el-button type="primary" @click="syncFromJson">同步到可视化编辑器</el-button>
            </div>
          </div>
        </el-tab-pane>

        <!-- 预览 -->
        <el-tab-pane label="预览" name="preview">
          <div class="schema-preview">
            <h4>生成的JSON Schema:</h4>
            <pre class="schema-code">{{ formattedSchema }}</pre>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>

    <!-- 操作按钮 -->
    <div class="editor-actions">
      <el-button @click="handleCancel">取消</el-button>
      <el-button type="primary" @click="handleSave">保存</el-button>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Delete } from '@element-plus/icons-vue'

// Props
const props = defineProps({
  schema: {
    type: String,
    default: ''
  },
  type: {
    type: String,
    default: 'input' // input, output, config
  }
})

// Emits
const emit = defineEmits(['save', 'cancel'])

// 响应式数据
const activeTab = ref('visual')
const jsonSchema = ref('')

// Schema基本信息
const schemaInfo = reactive({
  type: 'object',
  title: '',
  description: ''
})

// 对象属性
const properties = ref([])

// 数组项配置
const arrayItems = reactive({
  type: 'string',
  description: '',
  minItems: 0,
  maxItems: undefined
})

// 计算属性
const formattedSchema = computed(() => {
  try {
    const schema = generateSchema()
    return JSON.stringify(schema, null, 2)
  } catch (error) {
    return '无效的Schema配置'
  }
})

// 方法定义
const initEditor = () => {
  if (props.schema) {
    try {
      const parsed = JSON.parse(props.schema)
      parseSchema(parsed)
      jsonSchema.value = JSON.stringify(parsed, null, 2)
    } catch (error) {
      jsonSchema.value = props.schema
      // 设置默认值
      setDefaultSchema()
    }
  } else {
    setDefaultSchema()
  }
}

const setDefaultSchema = () => {
  const defaultSchemas = {
    input: {
      type: 'object',
      title: '输入参数',
      description: '节点的输入参数定义',
      properties: {
        data: {
          type: 'object',
          description: '输入数据'
        },
        context: {
          type: 'object',
          description: '上下文数据'
        }
      },
      required: ['data']
    },
    output: {
      type: 'object',
      title: '输出参数',
      description: '节点的输出参数定义',
      properties: {
        result: {
          type: 'object',
          description: '处理结果'
        },
        success: {
          type: 'boolean',
          description: '是否成功'
        }
      },
      required: ['result', 'success']
    },
    config: {
      type: 'object',
      title: '配置参数',
      description: '节点的配置参数定义',
      properties: {
        timeout: {
          type: 'integer',
          description: '超时时间(秒)',
          default: 30,
          minimum: 1,
          maximum: 3600
        }
      }
    }
  }
  
  const defaultSchema = defaultSchemas[props.type] || defaultSchemas.input
  parseSchema(defaultSchema)
  jsonSchema.value = JSON.stringify(defaultSchema, null, 2)
}

const parseSchema = (schema) => {
  schemaInfo.type = schema.type || 'object'
  schemaInfo.title = schema.title || ''
  schemaInfo.description = schema.description || ''
  
  if (schema.type === 'object' && schema.properties) {
    properties.value = Object.entries(schema.properties).map(([name, prop]) => ({
      name,
      type: prop.type || 'string',
      description: prop.description || '',
      default: prop.default || '',
      required: schema.required?.includes(name) || false,
      minLength: prop.minLength,
      maxLength: prop.maxLength,
      pattern: prop.pattern,
      minimum: prop.minimum,
      maximum: prop.maximum,
      multipleOf: prop.multipleOf,
      enum: prop.enum || []
    }))
  } else {
    properties.value = []
  }
  
  if (schema.type === 'array' && schema.items) {
    arrayItems.type = schema.items.type || 'string'
    arrayItems.description = schema.items.description || ''
    arrayItems.minItems = schema.minItems
    arrayItems.maxItems = schema.maxItems
  }
}

const generateSchema = () => {
  const schema = {
    type: schemaInfo.type
  }
  
  if (schemaInfo.title) {
    schema.title = schemaInfo.title
  }
  
  if (schemaInfo.description) {
    schema.description = schemaInfo.description
  }
  
  if (schemaInfo.type === 'object') {
    schema.properties = {}
    schema.required = []
    
    properties.value.forEach(prop => {
      if (!prop.name) return
      
      const propSchema = {
        type: prop.type
      }
      
      if (prop.description) {
        propSchema.description = prop.description
      }
      
      if (prop.default !== undefined && prop.default !== '') {
        propSchema.default = prop.default
      }
      
      // 字符串类型的额外配置
      if (prop.type === 'string') {
        if (prop.minLength !== undefined) propSchema.minLength = prop.minLength
        if (prop.maxLength !== undefined) propSchema.maxLength = prop.maxLength
        if (prop.pattern) propSchema.pattern = prop.pattern
      }
      
      // 数字类型的额外配置
      if (['number', 'integer'].includes(prop.type)) {
        if (prop.minimum !== undefined) propSchema.minimum = prop.minimum
        if (prop.maximum !== undefined) propSchema.maximum = prop.maximum
        if (prop.multipleOf !== undefined) propSchema.multipleOf = prop.multipleOf
      }
      
      // 枚举值
      if (prop.enum && prop.enum.length > 0) {
        propSchema.enum = prop.enum
      }
      
      schema.properties[prop.name] = propSchema
      
      if (prop.required) {
        schema.required.push(prop.name)
      }
    })
    
    if (schema.required.length === 0) {
      delete schema.required
    }
  } else if (schemaInfo.type === 'array') {
    schema.items = {
      type: arrayItems.type
    }
    
    if (arrayItems.description) {
      schema.items.description = arrayItems.description
    }
    
    if (arrayItems.minItems !== undefined) {
      schema.minItems = arrayItems.minItems
    }
    
    if (arrayItems.maxItems !== undefined) {
      schema.maxItems = arrayItems.maxItems
    }
  }
  
  return schema
}

const addProperty = () => {
  properties.value.push({
    name: '',
    type: 'string',
    description: '',
    default: '',
    required: false,
    enum: []
  })
}

const removeProperty = (index) => {
  properties.value.splice(index, 1)
}

const formatJson = () => {
  try {
    const parsed = JSON.parse(jsonSchema.value)
    jsonSchema.value = JSON.stringify(parsed, null, 2)
    ElMessage.success('格式化成功')
  } catch (error) {
    ElMessage.error('JSON格式错误：' + error.message)
  }
}

const validateJson = () => {
  try {
    JSON.parse(jsonSchema.value)
    ElMessage.success('JSON格式正确')
  } catch (error) {
    ElMessage.error('JSON格式错误：' + error.message)
  }
}

const syncFromJson = () => {
  try {
    const parsed = JSON.parse(jsonSchema.value)
    parseSchema(parsed)
    ElMessage.success('同步成功')
  } catch (error) {
    ElMessage.error('JSON格式错误，无法同步：' + error.message)
  }
}

const handleSave = () => {
  try {
    let schema
    if (activeTab.value === 'json') {
      // 验证JSON格式
      JSON.parse(jsonSchema.value)
      schema = jsonSchema.value
    } else {
      // 从可视化编辑器生成
      const generated = generateSchema()
      schema = JSON.stringify(generated, null, 2)
    }
    
    emit('save', schema)
  } catch (error) {
    ElMessage.error('保存失败：' + error.message)
  }
}

const handleCancel = () => {
  emit('cancel')
}

// 监听可视化编辑器的变化，同步到JSON编辑器
watch(
  [schemaInfo, properties, arrayItems],
  () => {
    if (activeTab.value === 'visual') {
      try {
        const schema = generateSchema()
        jsonSchema.value = JSON.stringify(schema, null, 2)
      } catch (error) {
        // 忽略生成错误
      }
    }
  },
  { deep: true }
)

// 生命周期
onMounted(() => {
  initEditor()
})
</script>

<style scoped>
.schema-editor {
  height: 100%;
  min-height: 500px;
  display: flex;
  flex-direction: column;
}

.editor-tabs {
  flex: 1;
  overflow: hidden;
}

.editor-tabs :deep(.el-tabs__content) {
  height: calc(100% - 40px);
  overflow-y: auto;
}

.visual-editor {
  padding: 20px;
  height: 100%;
  overflow-y: auto;
}

.schema-info {
  margin-bottom: 20px;
  padding: 16px;
  background: #f5f7fa;
  border-radius: 4px;
}

.properties-editor {
  margin-top: 20px;
}

.properties-list {
  max-height: 400px;
  overflow-y: auto;
  padding-right: 8px;
}

.properties-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
}

.properties-header h4 {
  margin: 0;
  color: #303133;
}

.property-item {
  margin-bottom: 16px;
}

.property-card {
  border: 1px solid #e4e7ed;
}

.property-card :deep(.el-card__body) {
  padding: 20px;
}

.property-card .el-form-item {
  margin-bottom: 12px;
}

.property-card .el-row {
  margin-bottom: 8px;
}

.type-config {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid #ebeef5;
}

.enum-config {
  margin-top: 12px;
}

.array-editor {
  padding: 20px;
}

.array-editor h4 {
  margin: 0 0 16px 0;
  color: #303133;
}

.json-editor {
  padding: 20px;
  height: 100%;
  display: flex;
  flex-direction: column;
}

.json-textarea {
  flex: 1;
}

.json-textarea :deep(.el-textarea__inner) {
  font-family: 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.5;
}

.json-actions {
  margin-top: 12px;
  display: flex;
  gap: 12px;
}

.schema-preview {
  padding: 20px;
}

.schema-preview h4 {
  margin: 0 0 16px 0;
  color: #303133;
}

.schema-code {
  background: #f5f7fa;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  padding: 16px;
  font-family: 'Courier New', monospace;
  font-size: 14px;
  line-height: 1.5;
  overflow-x: auto;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.editor-actions {
  padding: 16px 20px;
  border-top: 1px solid #ebeef5;
  display: flex;
  justify-content: flex-end;
  gap: 12px;
}
</style>